﻿#include "linedetect.h"

//
int linedetectprocess(matrix inimg, matrix outimg,matrix gtable, int mflag)
{
	if (inimg.data == NULL || inimg.w == 0) {
		std::cout << "image empty!" << endl;
		return FALSE;
	}
	//uchar* pgray=NULL;
	matrix pgray, linemap;

	memcpy(&pgray, &inimg, sizeof(matrix));
	memcpy(&linemap, &inimg, sizeof(matrix));
	linemap.channel = pgray.channel = 1;
	if (inimg.channel > 1) {
		std::cout << "input is not gray image!" << endl;
		pgray.data = GetGrayimg0(inimg);
		//return FALSE;
	}
	else {
		pgray.data = inimg.data;
	}

	int sum = 0;
	for (int r = 0; r < gtable.h; r++)                    //get sum of table
		for (int c = 0; c < gtable.w; c++)
			sum += ((int*)gtable.d)[r * gtable.w + c];
	gtable.sum = sum;
	Conv2D(pgray, pgray, gtable);			//gaussion filter

	linemap.data = NULL;
	linemap.data = (uchar*)malloc(sizeof(uchar) * linemap.w * linemap.h);
	if (linemap.data == NULL) {
		std::cout << "can not malloc memory to edgemap" << endl;
		return FALSE;
	}
	memset(linemap.data, 0, linemap.w * linemap.h);
	InitPointTypes();
	int r, c, row= linemap.h, col= linemap.w,ksw=9,ksh=9,i,n,sr,sc;
	int ps = (ksw - 1) >> 1,x0,y0,x1,y1,x2,y2;		//padding size
	uchar table[255] = { 0 };
	SetGammaTable(table, 255, 0.3);
	Mat tempimg=Mat(inimg.h,inimg.w,CV_8UC3), grayimgtemp = Mat(inimg.h, inimg.w, CV_8UC1),templingmap;
	templingmap = Mat(inimg.h, inimg.w, CV_8UC1);
	memcpy(tempimg.data, inimg.data, inimg.w* inimg.h* inimg.channel);
	memcpy(grayimgtemp.data, pgray.data, pgray.w * pgray.h * pgray.channel);
	memcpy(templingmap.data, linemap.data, linemap.w * linemap.h * linemap.channel);

	//CreateDebugImg();
	for (r = 0; r < row; r++) {
		if (r - ps < 0 || r + ps >= row)
			continue;
		//if(r == 10)
		//	cout << "正在执行" << endl;
		//
		//if (r == (row >> 3)) {
		//	memcpy(templingmap.data, linemap.data, linemap.w * linemap.h * linemap.channel);
		//	cout << "完成12.5%" << endl;
		//}
		//if (r == (row >> 2)) {
		//	cout << "完成25%" << endl;
		//	memcpy(templingmap.data, linemap.data, linemap.w * linemap.h * linemap.channel);
		//}
		//if (r == (row >> 1)) {
		//	memcpy(templingmap.data, linemap.data, linemap.w * linemap.h * linemap.channel);
		//	cout << "完成50%" << endl;
		//}
		//if (r == ((row >> 2) + (row >> 1))) {
		//	memcpy(templingmap.data, linemap.data, linemap.w * linemap.h * linemap.channel);
		//	cout << "完成75%" << endl;
		//}
		for (c = 0; c < col; c++) {
			if (r - ps < 0 || r + ps >= row || c - ps < 0 || c + ps >= col) {
				continue;
			}
			bool l1 , l2 , l = false,templine;
			int templv=0,maxl=0,t;
			int sumlv, linelv = 0;
			//printf("(%d,%d):%d\t", r, c, pgray.data[r * pgray.w + c]);
			if (r == 23 && c == 2174) {
				int a;
				a = 0;
			}
			x0 = c - ps;
			y0 = r - ps;
			linelv = 0;
			for (i = 0; i < PointTypesNum; i++) {
				//if (i != 1)
				//	continue;
				templine = true;
				sumlv = 0;
				l1 = l2 = true;
				for (n = 0; n < PointTypes[i].size; n++) {
					x1 = PointTypes[i].pts1[n].x + x0;
					y1 = PointTypes[i].pts1[n].y + y0;
					x2 = PointTypes[i].pts2[n].x + x0;
					y2 = PointTypes[i].pts2[n].y + y0;
					sumlv = t = pgray.data[y1 * pgray.w + x1] - pgray.data[y2 * pgray.w + x2];	
					if (l1) {							
						l1 = (l1 &&  (t> Linethres[i]));
					}
					if (l2){
						l2 = (l2 && (t < -Linethres[i]));							
					}
					templine = l1 || l2;
					if (!templine) {
						break;
					}
				}
				if (templine) {
					sumlv = abs(int(double(sumlv) / (PointTypes[i].size)));
					linelv = intmax(linelv, sumlv);
					l = true;
				}
			}
			if (l) {
				//sumlv += 20;
				linemap.data[r * linemap.w + c] = 255;// table[linelv];
				if (table[linelv] <= 0) {
					cout << "warning! sumlv is too less .y:" << r << "\tx:" << c << endl;;
				}
			}
			else {
				linemap.data[r * linemap.w + c] = 0;
			}
		}
	}
	//writeMat(linemap, "/mark/linemap.ppm", PPM_P6_OUT);

	memcpy(templingmap.data, linemap.data, linemap.w* linemap.h* linemap.channel);

	writeMat(linemap, "mark/linemap.ppm", PPM_P6_OUT);

	free(pgray.data);
	free(linemap.data);
	FreePointTypes();
	return 0;
}

//free memory
void FreePointTypes()
{
	MyPoint* pts1 = NULL, * pts2 = NULL;
	for (int i = 0; i < PointTypesNum; i++) {
		pts1 = PointTypes[i].pts1;
		pts2 = PointTypes[i].pts2;
		if (pts1 != NULL || pts2 != NULL) {
			free(pts1);
			free(pts2);
			PointTypes[i].pts1 = NULL;
			PointTypes[i].pts2 = NULL;
		}
		else {
			std::cout << "错误-无需释放PointTypes" << endl;
			return;
		}
	}
}

//init PointType
void InitPointTypes()
{
	memset(PointTypes, 0, sizeof(PointTypes));
	MyPoint* p=NULL;		
	for (int i = 0; i < PointTypesNum; i++) {
		Linethres[i] = 40;
		switch (i)
		{
		case LINE_DETECT_TYPE_1:
			PointTypes[i].size = 7;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * 7);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_1>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 3;
			p[1].x = 2, p[1].y = 3;
			p[2].x = 3, p[2].y = 3;
			p[3].x = 4, p[3].y = 3;
			p[4].x = 5, p[4].y = 3;
			p[5].x = 6, p[5].y = 3;
			p[6].x = 7, p[6].y = 3;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * 7);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_1>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 5;
			p[1].x = 2, p[1].y = 5;
			p[2].x = 3, p[2].y = 5;
			p[3].x = 4, p[3].y = 5;
			p[4].x = 5, p[4].y = 5;
			p[5].x = 6, p[5].y = 5;
			p[6].x = 7, p[6].y = 5;
			break;
		case LINE_DETECT_TYPE_2:
			PointTypes[i].size = 7;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * 7);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_2>" << endl;
				return;
			}
			p[0].x = 3, p[0].y = 1;
			p[1].x = 3, p[1].y = 2;
			p[2].x = 3, p[2].y = 3;
			p[3].x = 3, p[3].y = 4;
			p[4].x = 3, p[4].y = 5;
			p[5].x = 3, p[5].y = 6;
			p[6].x = 3, p[6].y = 7;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * 7);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_2>" << endl;
				return;
			}
			p[0].x = 5, p[0].y = 1;
			p[1].x = 5, p[1].y = 2;
			p[2].x = 5, p[2].y = 3;
			p[3].x = 5, p[3].y = 4;
			p[4].x = 5, p[4].y = 5;
			p[5].x = 5, p[5].y = 6;
			p[6].x = 5, p[6].y = 7;
			break;
		case LINE_DETECT_TYPE_3:
			PointTypes[i].size = 7;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * 7);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_3>" << endl;
				return;
			}
			p[0].x = 2, p[0].y = 0;
			p[1].x = 3, p[1].y = 1;
			p[2].x = 4, p[2].y = 2;
			p[3].x = 5, p[3].y = 3;
			p[4].x = 6, p[4].y = 4;
			p[5].x = 7, p[5].y = 5;
			p[6].x = 8, p[6].y = 6;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * 7);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_3>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 2;
			p[1].x = 2, p[1].y = 3;
			p[2].x = 3, p[2].y = 4;
			p[3].x = 4, p[3].y = 5;
			p[4].x = 5, p[4].y = 6;
			p[5].x = 6, p[5].y = 7;
			p[6].x = 7, p[6].y = 8;
			break;
		case LINE_DETECT_TYPE_4:
			PointTypes[i].size = 7;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * 7);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_4>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 6;
			p[1].x = 1, p[1].y = 5;
			p[2].x = 2, p[2].y = 4;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 4, p[4].y = 2;
			p[5].x = 5, p[5].y = 1;
			p[6].x = 6, p[6].y = 0;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * 7);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_4>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 8;
			p[1].x = 2, p[1].y = 7;
			p[2].x = 3, p[2].y = 6;
			p[3].x = 4, p[3].y = 5;
			p[4].x = 5, p[4].y = 4;
			p[5].x = 6, p[5].y = 3;
			p[6].x = 7, p[6].y = 2;
			break;
		case LINE_DETECT_TYPE_5:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_5>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 0;
			p[1].x = 2, p[1].y = 1;
			p[2].x = 3, p[2].y = 2;
			p[3].x = 4, p[3].y = 3;
			p[4].x = 5, p[4].y = 3;
			p[5].x = 6, p[5].y = 4;
			p[6].x = 7, p[6].y = 5;
			p[7].x = 8, p[7].y = 6;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_5>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 2;
			p[1].x = 2, p[1].y = 3;
			p[2].x = 3, p[2].y = 4;
			p[3].x = 4, p[3].y = 5;
			p[4].x = 5, p[4].y = 5;
			p[5].x = 6, p[5].y = 6;
			p[6].x = 7, p[6].y = 7;
			p[7].x = 8, p[7].y = 8;
			break;
		case LINE_DETECT_TYPE_6:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_6>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 6;
			p[1].x = 1, p[1].y = 5;
			p[2].x = 2, p[2].y = 4;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 2;
			p[6].x = 6, p[6].y = 1;
			p[7].x = 7, p[7].y = 0;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_6>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 8;
			p[1].x = 1, p[1].y = 7;
			p[2].x = 2, p[2].y = 6;
			p[3].x = 3, p[3].y = 5;
			p[4].x = 4, p[4].y = 5;
			p[5].x = 5, p[5].y = 4;
			p[6].x = 6, p[6].y = 3;
			p[7].x = 7, p[7].y = 2;
			break;
		case LINE_DETECT_TYPE_7:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_7>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 1;
			p[1].x = 2, p[1].y = 2;
			p[2].x = 3, p[2].y = 2;
			p[3].x = 4, p[3].y = 3;
			p[4].x = 5, p[4].y = 4;
			p[5].x = 6, p[5].y = 5;
			p[6].x = 7, p[6].y = 5;
			p[7].x = 8, p[7].y = 6;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_7>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 3;
			p[1].x = 2, p[1].y = 4;
			p[2].x = 3, p[2].y = 4;
			p[3].x = 4, p[3].y = 5;
			p[4].x = 5, p[4].y = 6;
			p[5].x = 6, p[5].y = 7;
			p[6].x = 7, p[6].y = 7;
			p[7].x = 8, p[7].y = 8;
			break;
		case LINE_DETECT_TYPE_8:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_8>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 6;
			p[1].x = 1, p[1].y = 5;
			p[2].x = 2, p[2].y = 5;
			p[3].x = 3, p[3].y = 4;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 2;
			p[6].x = 6, p[6].y = 2;
			p[7].x = 7, p[7].y = 1;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_8>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 8;
			p[1].x = 1, p[1].y = 7;
			p[2].x = 2, p[2].y = 7;
			p[3].x = 3, p[3].y = 6;
			p[4].x = 4, p[4].y = 5;
			p[5].x = 5, p[5].y = 4;
			p[6].x = 6, p[6].y = 4;
			p[7].x = 7, p[7].y = 3;
			break;
		case LINE_DETECT_TYPE_9:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_9>" << endl;
				return;
			}
			p[0].x = 2, p[0].y = 0;
			p[1].x = 3, p[1].y = 1;
			p[2].x = 4, p[2].y = 2;
			p[3].x = 5, p[3].y = 3;
			p[4].x = 5, p[4].y = 4;
			p[5].x = 6, p[5].y = 5;
			p[6].x = 7, p[6].y = 6;
			p[7].x = 8, p[7].y = 7;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_9>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 0;
			p[1].x = 1, p[1].y = 1;
			p[2].x = 2, p[2].y = 2;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 3, p[4].y = 4;
			p[5].x = 4, p[5].y = 5;
			p[6].x = 5, p[6].y = 6;
			p[7].x = 6, p[7].y = 7;
			break;
		case LINE_DETECT_TYPE_10:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_10>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 7;
			p[1].x = 1, p[1].y = 6;
			p[2].x = 2, p[2].y = 5;
			p[3].x = 3, p[3].y = 4;
			p[4].x = 3, p[4].y = 3;
			p[5].x = 4, p[5].y = 2;
			p[6].x = 5, p[6].y = 1;
			p[7].x = 6, p[7].y = 0;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_10>" << endl;
				return;
			}
			p[0].x = 2, p[0].y = 7;
			p[1].x = 3, p[1].y = 6;
			p[2].x = 4, p[2].y = 5;
			p[3].x = 5, p[3].y = 4;
			p[4].x = 5, p[4].y = 3;
			p[5].x = 6, p[5].y = 2;
			p[6].x = 7, p[6].y = 1;
			p[7].x = 8, p[7].y = 0;
			break;
		case LINE_DETECT_TYPE_11:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_11>" << endl;
				return;
			}
			p[0].x = 2, p[0].y = 0;
			p[1].x = 3, p[1].y = 1;
			p[2].x = 3, p[2].y = 2;
			p[3].x = 4, p[3].y = 3;
			p[4].x = 5, p[4].y = 4;
			p[5].x = 6, p[5].y = 5;
			p[6].x = 6, p[6].y = 6;
			p[7].x = 7, p[7].y = 7;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_11>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 0;
			p[1].x = 1, p[1].y = 1;
			p[2].x = 1, p[2].y = 2;
			p[3].x = 2, p[3].y = 3;
			p[4].x = 3, p[4].y = 4;
			p[5].x = 4, p[5].y = 5;
			p[6].x = 4, p[6].y = 6;
			p[7].x = 5, p[7].y = 7;
			break;
		case LINE_DETECT_TYPE_12:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_12>" << endl;
				return;
			}
			p[0].x = 3, p[0].y = 7;
			p[1].x = 4, p[1].y = 6;
			p[2].x = 4, p[2].y = 5;
			p[3].x = 5, p[3].y = 4;
			p[4].x = 6, p[4].y = 3;
			p[5].x = 7, p[5].y = 2;
			p[6].x = 7, p[6].y = 1;
			p[7].x = 8, p[7].y = 0;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_12>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 7;
			p[1].x = 2, p[1].y = 6;
			p[2].x = 2, p[2].y = 5;
			p[3].x = 3, p[3].y = 4;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 2;
			p[6].x = 5, p[6].y = 1;
			p[7].x = 6, p[7].y = 0;
			break;
		case LINE_DETECT_TYPE_13:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_13>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 5;
			p[1].x = 1, p[1].y = 5;
			p[2].x = 2, p[2].y = 4;
			p[3].x = 3, p[3].y = 4;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 3;
			p[6].x = 6, p[6].y = 2;
			p[7].x = 7, p[7].y = 2;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_13>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 7;
			p[1].x = 2, p[1].y = 7;
			p[2].x = 3, p[2].y = 6;
			p[3].x = 4, p[3].y = 6;
			p[4].x = 5, p[4].y = 5;
			p[5].x = 6, p[5].y = 5;
			p[6].x = 7, p[6].y = 4;
			p[7].x = 8, p[7].y = 4;
			break;
		case LINE_DETECT_TYPE_14:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_14>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 2;
			p[1].x = 2, p[1].y = 2;
			p[2].x = 3, p[2].y = 3;
			p[3].x = 4, p[3].y = 3;
			p[4].x = 5, p[4].y = 4;
			p[5].x = 6, p[5].y = 4;
			p[6].x = 7, p[6].y = 5;
			p[7].x = 8, p[7].y = 5;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_14>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 4;
			p[1].x = 1, p[1].y = 4;
			p[2].x = 2, p[2].y = 5;
			p[3].x = 3, p[3].y = 5;
			p[4].x = 4, p[4].y = 6;
			p[5].x = 5, p[5].y = 6;
			p[6].x = 6, p[6].y = 7;
			p[7].x = 7, p[7].y = 7;
			break;
		case LINE_DETECT_TYPE_15:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_15>" << endl;
				return;
			}
			p[0].x = 3, p[0].y = 0;
			p[1].x = 3, p[1].y = 1;
			p[2].x = 4, p[2].y = 2;
			p[3].x = 4, p[3].y = 3;
			p[4].x = 5, p[4].y = 4;
			p[5].x = 5, p[5].y = 5;
			p[6].x = 6, p[6].y = 6;
			p[7].x = 6, p[7].y = 7;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_15>" << endl;
				return;
			}
			p[0].x = 1, p[0].y = 1;
			p[1].x = 1, p[1].y = 2;
			p[2].x = 2, p[2].y = 3;
			p[3].x = 2, p[3].y = 4;
			p[4].x = 3, p[4].y = 5;
			p[5].x = 3, p[5].y = 6;
			p[6].x = 4, p[6].y = 7;
			p[7].x = 4, p[7].y = 8;
			break;
		case LINE_DETECT_TYPE_16:
			PointTypes[i].size = 8;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_16>" << endl;
				return;
			}
			p[0].x = 2, p[0].y = 7;
			p[1].x = 2, p[1].y = 6;
			p[2].x = 3, p[2].y = 5;
			p[3].x = 3, p[3].y = 4;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 4, p[5].y = 2;
			p[6].x = 5, p[6].y = 1;
			p[7].x = 5, p[7].y = 0;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_16>" << endl;
				return;
			}
			p[0].x = 4, p[0].y = 8;
			p[1].x = 4, p[1].y = 7;
			p[2].x = 5, p[2].y = 6;
			p[3].x = 5, p[3].y = 5;
			p[4].x = 6, p[4].y = 4;
			p[5].x = 6, p[5].y = 3;
			p[6].x = 7, p[6].y = 2;
			p[7].x = 7, p[7].y = 1;
			break;
		case LINE_DETECT_TYPE_17:
			PointTypes[i].size = 9;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_17>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 4;
			p[1].x = 1, p[1].y = 4;
			p[2].x = 2, p[2].y = 4;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 3;
			p[6].x = 6, p[6].y = 2;
			p[7].x = 7, p[7].y = 2;
			p[8].x = 8, p[8].y = 2;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_17>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 6;
			p[1].x = 1, p[1].y = 6;
			p[2].x = 2, p[2].y = 6;
			p[3].x = 3, p[3].y = 5;
			p[4].x = 4, p[4].y = 5;
			p[5].x = 5, p[5].y = 5;
			p[6].x = 6, p[6].y = 4;
			p[7].x = 7, p[7].y = 4;
			p[8].x = 8, p[8].y = 4;
			break;
		case LINE_DETECT_TYPE_18:
			PointTypes[i].size = 9;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_18>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 2;
			p[1].x = 1, p[1].y = 2;
			p[2].x = 2, p[2].y = 2;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 3;
			p[6].x = 6, p[6].y = 4;
			p[7].x = 7, p[7].y = 4;
			p[8].x = 8, p[8].y = 4;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_18>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 4;
			p[1].x = 1, p[1].y = 4;
			p[2].x = 2, p[2].y = 4;
			p[3].x = 3, p[3].y = 5;
			p[4].x = 4, p[4].y = 5;
			p[5].x = 5, p[5].y = 5;
			p[6].x = 6, p[6].y = 6;
			p[7].x = 7, p[7].y = 6;
			p[8].x = 8, p[8].y = 6;
			break;
		case LINE_DETECT_TYPE_19:
			PointTypes[i].size = 9;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_19>" << endl;
				return;
			}
			p[0].x = 4, p[0].y = 0;
			p[1].x = 4, p[1].y = 1;
			p[2].x = 4, p[2].y = 2;
			p[3].x = 5, p[3].y = 3;
			p[4].x = 5, p[4].y = 4;
			p[5].x = 5, p[5].y = 5;
			p[6].x = 6, p[6].y = 6;
			p[7].x = 6, p[7].y = 7;
			p[8].x = 6, p[8].y = 8;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_19>" << endl;
				return;
			}
			p[0].x = 2, p[0].y = 0;
			p[1].x = 2, p[1].y = 1;
			p[2].x = 2, p[2].y = 2;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 3, p[4].y = 4;
			p[5].x = 3, p[5].y = 5;
			p[6].x = 4, p[6].y = 6;
			p[7].x = 4, p[7].y = 7;
			p[8].x = 4, p[8].y = 8;
			break;
		case LINE_DETECT_TYPE_20:
			PointTypes[i].size = 9;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 4, p[0].y = 0;
			p[1].x = 4, p[1].y = 1;
			p[2].x = 4, p[2].y = 2;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 3, p[4].y = 4;
			p[5].x = 3, p[5].y = 5;
			p[6].x = 2, p[6].y = 6;
			p[7].x = 2, p[7].y = 7;
			p[8].x = 2, p[8].y = 8;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 6, p[0].y = 0;
			p[1].x = 6, p[1].y = 1;
			p[2].x = 6, p[2].y = 2;
			p[3].x = 5, p[3].y = 3;
			p[4].x = 5, p[4].y = 4;
			p[5].x = 5, p[5].y = 5;
			p[6].x = 4, p[6].y = 6;
			p[7].x = 4, p[7].y = 7;
			p[8].x = 4, p[8].y = 8;
			break;
		case LINE_DETECT_TYPE_21:
			PointTypes[i].size = 9;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 4;
			p[1].x = 1, p[1].y = 4;
			p[2].x = 2, p[2].y = 4;
			p[3].x = 3, p[3].y = 4;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 3;
			p[6].x = 6, p[6].y = 3;
			p[7].x = 7, p[7].y = 3;
			p[8].x = 8, p[8].y = 3;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 6;
			p[1].x = 1, p[1].y = 6;
			p[2].x = 2, p[2].y = 6;
			p[3].x = 3, p[3].y = 6;
			p[4].x = 4, p[4].y = 5;
			p[5].x = 5, p[5].y = 5;
			p[6].x = 6, p[6].y = 5;
			p[7].x = 7, p[7].y = 5;
			p[8].x = 8, p[8].y = 5;
			break;
		case LINE_DETECT_TYPE_22:
			PointTypes[i].size = 9;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 3;
			p[1].x = 1, p[1].y = 3;
			p[2].x = 2, p[2].y = 3;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 4, p[4].y = 4;
			p[5].x = 5, p[5].y = 4;
			p[6].x = 6, p[6].y = 4;
			p[7].x = 7, p[7].y = 4;
			p[8].x = 8, p[8].y = 4;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 5;
			p[1].x = 1, p[1].y = 5;
			p[2].x = 2, p[2].y = 5;
			p[3].x = 3, p[3].y = 5;
			p[4].x = 4, p[4].y = 6;
			p[5].x = 5, p[5].y = 6;
			p[6].x = 6, p[6].y = 6;
			p[7].x = 7, p[7].y = 6;
			p[8].x = 8, p[8].y = 6;
			break;
		case LINE_DETECT_TYPE_23:
			PointTypes[i].size = 9;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 4;
			p[1].x = 1, p[1].y = 4;
			p[2].x = 2, p[2].y = 3;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 3;
			p[6].x = 6, p[6].y = 2;
			p[7].x = 7, p[7].y = 2;
			p[8].x = 8, p[8].y = 2;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 6;
			p[1].x = 1, p[1].y = 6;
			p[2].x = 2, p[2].y = 5;
			p[3].x = 3, p[3].y = 5;
			p[4].x = 4, p[4].y = 5;
			p[5].x = 5, p[5].y = 5;
			p[6].x = 6, p[6].y = 4;
			p[7].x = 7, p[7].y = 4;
			p[8].x = 8, p[8].y = 4;
			break;
		case LINE_DETECT_TYPE_24:
			PointTypes[i].size = 9;
			PointTypes[i].pts1 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 2;
			p[1].x = 1, p[1].y = 2;
			p[2].x = 2, p[2].y = 3;
			p[3].x = 3, p[3].y = 3;
			p[4].x = 4, p[4].y = 3;
			p[5].x = 5, p[5].y = 3;
			p[6].x = 6, p[6].y = 4;
			p[7].x = 7, p[7].y = 4;
			p[8].x = 8, p[8].y = 4;
			PointTypes[i].pts2 = p = (MyPoint*)malloc(sizeof(MyPoint) * PointTypes[i].size);
			if (p == NULL) {
				std::cout << "can not malloc memory to <LINE_DETECT_TYPE_20>" << endl;
				return;
			}
			p[0].x = 0, p[0].y = 4;
			p[1].x = 1, p[1].y = 4;
			p[2].x = 2, p[2].y = 5;
			p[3].x = 3, p[3].y = 5;
			p[4].x = 4, p[4].y = 5;
			p[5].x = 5, p[5].y = 5;
			p[6].x = 6, p[6].y = 6;
			p[7].x = 7, p[7].y = 6;
			p[8].x = 8, p[8].y = 6;
			break;

		default:
			break;
		}
	}

	std::cout << "PTS-INIT-finish" << endl;
}


void CreateDebugImg() {
	cout << "生成直线模板图像..." << endl;
	matrix img;
	img.channel = 3;
	img.w = img.h = 9;
	img.data = (uchar*)malloc(sizeof(img.w * img.h)*img.channel);
	int x, y;
	for (int i = 0; i < PointTypesNum; i++) {
		memset(img.data, 0, img.w * img.h * img.channel);
		for (int j = 0; j < PointTypes[i].size; j++) {
			x = PointTypes[i].pts1[j].x;
			y = PointTypes[i].pts1[j].y;
			img.data[(y * img.w + x) * img.channel] = 180;
			img.data[(y * img.w + x) * img.channel + 1] = 108;
			img.data[(y * img.w + x) * img.channel + 2] = 108;

			x = PointTypes[i].pts2[j].x;
			y = PointTypes[i].pts2[j].y;
			img.data[(y * img.w + x) * img.channel] = 250;
			img.data[(y * img.w + x) * img.channel + 1] = 10;
			img.data[(y * img.w + x) * img.channel + 2] = 10;
		}
		String path = "";
		path = format("mark/line-mask-%d.ppm", i);
		writeMat(img, path.c_str(), PPM_P6_OUT);
	}
	free(img.data);
}






